package com.example.demo.pipeline.config;

import com.example.demo.pipeline.context.TemplateContext;
import com.example.demo.pipeline.handler.TemplateHandler;
import com.example.demo.pipeline.handler.impl.CheckTemplateHandler;
import com.example.demo.pipeline.handler.impl.CreateTemplateHandler;
import com.example.demo.pipeline.handler.impl.SaveTemplateHandler;
import com.example.demo.pipeline.handler.impl.ValidatedTemplateHandler;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author liyuncong
 * @version 1.0
 * @file TemplateRouteConfig
 * @brief TemplateRouteConfig
 * @details TemplateRouteConfig
 * @date 2022-11-03
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                        NAME               DESCRIPTION
 * 2022-11-03                  liyuncong          Created
 */
@Configuration
public class TemplateRouteConfig implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    private final static Map<Class<? extends TemplateContext>,
        List<Class<? extends TemplateHandler<? extends TemplateContext>>>> TEMPLATE_ROUTE_MAP =
        new HashMap<>();

    /**
     * 启动创建管道上下文与管道处理器映射关系
     */
    static {
        TEMPLATE_ROUTE_MAP.put(TemplateContext.class, List.of(
            ValidatedTemplateHandler.class,
            CreateTemplateHandler.class,
            CheckTemplateHandler.class,
            SaveTemplateHandler.class
        ));
    }

    @Bean("templatePipelineRouteMap")
    public Map<Class<? extends TemplateContext>,
        List<? extends TemplateHandler<? extends TemplateContext>>> templatePipelineRouteMap() {
        return TEMPLATE_ROUTE_MAP
            .entrySet()
            .stream()
            .collect(Collectors.toMap(Map.Entry::getKey, this::toPipeline));
    }

    private List<? extends TemplateHandler<? extends TemplateContext>> toPipeline(
        Map.Entry<Class<? extends TemplateContext>,
            List<Class<? extends TemplateHandler<? extends TemplateContext>>>> entry
    ) {
        return entry.getValue()
            .stream()
            .map(applicationContext::getBean)
            .collect(Collectors.toList());
    }


    @Override

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
